package cn.cutie.clot.mq.store;

import cn.cutie.clot.mq.model.ClotMessage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.SneakyThrows;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Scanner;

/**
 * @Description:
 * @Author: Cutie
 * @CreateDate: 2024/7/15 22:19
 * @Version: 0.0.1
 */
public class StoreDemo {
    @SneakyThrows
    public static void main(String[] args) {
        String content = """
                this is a good file.
                this is a new line for store.
                """;
        int length = content.getBytes(StandardCharsets.UTF_8).length;
        System.out.println("content len : " + length);
        File file = new File("test.dat");
        if (!file.exists()){
            file.createNewFile();
        }

        Path path = Paths.get(file.getAbsolutePath());
        // 文件的内存映射
        try(FileChannel fileChannel = (FileChannel) Files.newByteChannel(path, StandardOpenOption.READ, StandardOpenOption.WRITE)){
            MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
            for (int i = 0; i < 10; i++) {
                System.out.println("write " + i + " times' position: " + mappedByteBuffer.position());
                ClotMessage<String> clotMessage = (ClotMessage<String>) ClotMessage.create(i+ ":" + content, null);
                String msg = JSON.toJSONString(clotMessage);
                Indexer.addEntry("test", mappedByteBuffer.position(), msg.getBytes(StandardCharsets.UTF_8).length);
                mappedByteBuffer.put(Charset.forName("UTF-8").encode(JSON.toJSONString(clotMessage)));
            }
            length += 2;
            ByteBuffer readOnlyBuffer = mappedByteBuffer.asReadOnlyBuffer();
            Scanner scanner = new Scanner(System.in);
            while(scanner.hasNext()){
                String line = scanner.nextLine();
                if ("q".equals(line)){
                    break;
                }
                System.out.println("in = " + line);
                int id = Integer.parseInt(line);
                Indexer.Entry entry = Indexer.getEntry("test", id);
                readOnlyBuffer.position(entry.getOffset());
                int len = entry.getLength();
                byte[] bytes = new byte[len];
                readOnlyBuffer.get(bytes, 0, len);
                String s = new String(bytes, StandardCharsets.UTF_8);
                System.out.println("read only : " + s);
                ClotMessage<String> message = JSON.parseObject(s, new TypeReference<ClotMessage<String>>() {
                });
                System.out.println("message.getBody(): " + message.getBody());
            }
        }
    }
}
